﻿using System;
using System.Collections.Specialized;
using System.Web;
using APILocawebGatewayUI.Nucleo;

namespace APILocawebGatewayUI.VISA
{

    public class GerenciadorVISA
    {


        public event ReenviadoHandler Reenviado;

        private HttpContext _context;

        public GerenciadorVISA(HttpContext context)
        {
            _context = context;

        }

        #region Propriedades

        /// <summary>
        /// Código de serviço de Comércio Eletrônico junto à Locaweb.
        /// </summary>
        internal string Identificacao
        {
            get { return APILocawebConfiguration.Instancia.Identificacao; }
        }

        /// <summary>
        /// Define o tipo de ambiente (teste ou producao).
        /// </summary>
        internal string Ambiente
        {
            get { return APILocawebConfiguration.Instancia.Visa.Ambiente; }
        }

        /// <summary>
        /// Código de filiação junto a VISA.
        /// </summary>
        internal string Filiacao
        {
            get { return APILocawebConfiguration.Instancia.Visa.Filiacao; }
        }


        private string _codigoTransacao;
        /// <summary>
        /// Código de identificação da transação.
        /// </summary>
        public string CodigoTransacao
        {
            get
            {
                return string.IsNullOrEmpty(_codigoTransacao) ? _context.Request["tid"] : _codigoTransacao;
            }
            private set { _codigoTransacao = value; }
        }


        private string _orderId;
        /// <summary>
        /// Número do pedido para controle interno da loja.
        /// </summary>
        public string NumeroDoPedido
        {
            get
            {
                return string.IsNullOrEmpty(_orderId) ? _context.Request["orderid"] : _orderId;
            }
            private set { _orderId = value; }
        }


        private string _codigoRespostaTransacao;
        /// <summary>
        /// Log Ref - Código de retorno da transação.
        /// </summary>
        public string CodigoRespostaTransacao
        {
            get
            {
                return string.IsNullOrEmpty(_codigoRespostaTransacao) ? _context.Request["lr"] : _codigoRespostaTransacao;
            }
            private set { _codigoRespostaTransacao = value; }
        }

        /// <summary>
        /// Retorna mensagem LR
        /// </summary>
        public string RespostaTransacao
        {
            get { return VisaUtilidades.PegaMensagemTransacao(Convert.ToInt16(this.CodigoRespostaTransacao)); }
        }


        private string _arp;
        /// <summary>
        /// Código de autorização da compra.
        /// </summary>
        public string Arp
        {
            get
            {
                return string.IsNullOrEmpty(_arp) ? _context.Request["arp"] : _arp;
            }
            private set { _arp = value; }
        }


        private string _mensagemTransacao;
        /// <summary>
        /// Descrição do campo LR.
        /// </summary>
        public string MensagemTransacao
        {
            get
            {

                return string.IsNullOrEmpty(_mensagemTransacao) ? _context.Request["ars"] : _mensagemTransacao;
            }
            private set { _mensagemTransacao = value; }
        }


        private string _campoLivre;

        /// <summary>
        /// Campo livre
        /// </summary>
        public string CampoLivre
        {
            get
            {
                return string.IsNullOrEmpty(_campoLivre) ? _context.Request["free"] : _campoLivre;
            }
            private set { _campoLivre = value; }
        }


        private string _valor;
        /// <summary>
        /// Valor total da transação
        /// </summary>
        public string Valor
        {
            get
            {
                return string.IsNullOrEmpty(_valor) ? _context.Request["price"] : _valor;
            }
            private set { _valor = value; }
        }

        /// <summary>
        /// Tipo de autenticacao da transação
        /// </summary>
        public string TipoAutenticacaoTransacao
        {
            get { return _context.Request["authenttype"]; }
        }

        private string _hashDoCartao;
        /// <summary>
        /// HASH do N.º do cartão (criptografado)
        /// </summary>
        public string HashDoCartao
        {
            get
            {
                return string.IsNullOrEmpty(_hashDoCartao) ? _context.Request["pan"] : _hashDoCartao;
            }
            private set { _hashDoCartao = value; }
        }


        private string _banco;
        /// <summary>
        /// Código do banco emissor do cartão
        /// </summary>
        public string Banco
        {
            get
            {
                return string.IsNullOrEmpty(_hashDoCartao) ? _context.Request["bank"] : _banco;
            }
            private set { _banco = value; }
        }

        /// <summary>
        /// Retorno do valor capturado. Formato = Código Moeda, Valor Capturado, Casas Decimais.
        /// </summary>
        public string RetornoValorCapturado
        {
            get { return _context.Request["cap"]; }
        }

        /// <summary>
        /// Retorna se a transação foi aprovada ou não - CodigoTransacao (tid) | CodigoRespostaTransacao (lr) | LrMensagem | RetornoValorCapturado (cap) | MensagemTransacao (ars) | CampoLivre (free) | ObterValorRetorno (arp) | NumeroDoPedido (orderid) | Valor (price) | HashDoCartao (pan) | Banco (bank)
        /// </summary>
        public bool EstaAprovada
        {
            get
            {   //Verifica se o lr já foi capturado
                if (String.IsNullOrEmpty(this.MensagemTransacao))
                    this.RealizaReenvio();

                return this.CodigoRespostaTransacao == "0";
            }
        }
        #endregion

        #region métodos

        /// <summary>
        /// Contacta o servidor de comercio eletronico para obter o status da transação (lr)
        /// </summary>
        /// <returns></returns>
        private void RealizaReenvio()
        {

            Utilidades.Debugar(FormasDePagamento.VISA, "Início da execução do reenvio", this);
            NameValueCollection queryString = new NameValueCollection
                                                  {
                                                      {"identificacao", this.Identificacao},
                                                      {"ambiente", this.Ambiente},
                                                      {"modulo", "VISAVBV"},
                                                      {"operacao", "Retorno"},
                                                      {"tid", this.CodigoTransacao},
                                                      {"URLRetornoVisa", HttpUtility.UrlEncode(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + HttpContext.Current.Request.FilePath)}
                                                  };
            Utilidades.Debugar(FormasDePagamento.VISA, "QueryString do Reenvio" + Utilidades.GerarQueryString(queryString), this);

            string fonte = Utilidades.RequisicaoPOST(queryString);

            this.CodigoRespostaTransacao = VisaUtilidades.ObterValorRetorno(fonte, "lr");
            this.CodigoTransacao = VisaUtilidades.ObterValorRetorno(fonte, "tid");
            this.CampoLivre = VisaUtilidades.ObterValorRetorno(fonte, "free");
            this.MensagemTransacao = VisaUtilidades.ObterValorRetorno(fonte, "ars");
            this.Arp = VisaUtilidades.ObterValorRetorno(fonte, "arp");
            this.NumeroDoPedido = VisaUtilidades.ObterValorRetorno(fonte, "orderid");
            this.Valor = VisaUtilidades.ObterValorRetorno(fonte, "price");
            this.HashDoCartao = VisaUtilidades.ObterValorRetorno(fonte, "pan");
            this.Banco = VisaUtilidades.ObterValorRetorno(fonte, "bank");

            Utilidades.Debugar(FormasDePagamento.VISA, "final da execução do reenvio", this);

            if (Reenviado != null)
            {
                Reenviado(this, new ReenviadoArgs(this.Identificacao));
            }

            
        }

        /// <summary>
        /// Realiza a captura - CodigoTransacao (tid) | CodigoRespostaTransacao (lr) | RetornoValorCapturado (cap) | MensagemTransacao (ars) | CampoLivre (free)
        /// </summary>
        /// <returns></returns>
        public bool RealizarCaptura()
        {
            Utilidades.Debugar(FormasDePagamento.VISA, "Início da execução da captura", this);

            if (Convert.ToInt32(this.CodigoRespostaTransacao) == 0)
            {
                if (String.IsNullOrEmpty(this.MensagemTransacao) || this.MensagemTransacao != "capturado")
                {
                    NameValueCollection queryStringCaptura = new NameValueCollection
                                                                 {
                                                                     {"tid", this.CodigoTransacao},
                                                                     {"ambiente", this.Ambiente},
                                                                     {"modulo", "VISAVBV"},
                                                                     {"Operacao", "Captura"},
                                                                     {"free", this.CampoLivre},
                                                                     {"identificacao", this.Identificacao}
                                                                 };

                    Utilidades.Debugar(FormasDePagamento.VISA, "Renderizando o form de apontamento para locaweb", this);
                    this._context.Response.ClearContent();
                    this._context.Response.Clear();
                    this._context.Response.Write(Utilidades.RequisicaoGET(APILocawebConfiguration.Instancia.Url, queryStringCaptura));
                    return false;
                }

                //Chegou até aqui a transação foi capturada
                Utilidades.Debugar(FormasDePagamento.VISA, "final da execução da captura", this);
                return true;
            }
            return false;
        }
        #endregion
    }

}
